package com.soxing.webrain.brush.service.zip;

import com.soxing.webrain.brush.api.zip.IReadZipStructService;
import com.soxing.webrain.brush.common.util.FileUtil;
import com.soxing.webrain.brush.common.util.MyFile;
import org.apache.commons.lang.StringUtils;
import org.apache.tools.zip.ZipEntry;
import org.apache.tools.zip.ZipFile;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;

import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.util.*;
import java.util.zip.ZipException;

@Service("readZipStructService")
public class ReadZipStructServiceImpl implements IReadZipStructService {

    /**
     * @param path
     * @return
     * @throws IOException
     * @throws FileNotFoundException
     * @throws ZipException
     */
    @Override
    public List<MyFile> readZipFile(String path) throws Exception {
        // 文件目录的容器
        List<MyFile> rList = new ArrayList<>();
        ZipFile zf = new ZipFile(path, "GBK");
        Enumeration<?> e = zf.getEntries();
        int id = 0;
        while (e.hasMoreElements()) {
            ZipEntry zentry = (ZipEntry) e.nextElement();
            String entryName = zentry.getName();

            rList.add(new MyFile(entryName, zentry.isDirectory(), zentry.getSize(), path));
        }
        zf.close();
        processMyFile(rList);
        return rList;
    }

    @Override
    public List<MyFile> readZipFilePath(String path) throws Exception {
        // 文件目录的容器
        List<MyFile> rList = new ArrayList<>();
        ZipFile zf = new ZipFile(path, "GBK");
        Enumeration<?> e = zf.getEntries();
        while (e.hasMoreElements()) {
            ZipEntry zentry = (ZipEntry) e.nextElement();
            String entryName = zentry.getName();
            String path1 = StringUtils.substringBeforeLast(path, ".") + "/" + entryName;
            rList.add(new MyFile(entryName, zentry.isDirectory(), zentry.getSize(), path1));
        }
        zf.close();
        processMyFile(rList);
        return rList;
    }

    @Override
    public MyFile getMyFile(String path) throws Exception {
        MyFile myFile = new MyFile();
        File zf = new File(path);
        String fileName = zf.getName();
        int idx = fileName.lastIndexOf("-");
        if (idx < 0) {
            idx = 0;
        } else {
            idx = idx + 1;
        }
        fileName = fileName.substring(idx);

        myFile.setId(0);
        myFile.setPid(0);
        myFile.setFileName(fileName);
        myFile.setDir(true);
        myFile.setSize(zf.length());
        myFile.setPath("/");

        List<MyFile> tmpMyFileList = readZipFile(path);

        for (MyFile tmpMyFile : tmpMyFileList) {
            boolean tmpDir = tmpMyFile.isDir();
            if (tmpDir) {
                continue;
            } else {
                if (tmpMyFile.getEntryName().endsWith(".zip")) {
                    String tmpFullPath = StringUtils.substringBeforeLast(tmpMyFile.getFullPath(), ".") + "/" + tmpMyFile.getEntryName();
                    tmpMyFile.setFullPath(tmpFullPath);
                }
            }
        }
        if (CollectionUtils.isEmpty(tmpMyFileList)) {
            return myFile;
        }

        Map<Integer, List<MyFile>> parentId2MyFileListMap = new HashMap<>();
        for (MyFile tmpMyFile : tmpMyFileList) {
            Integer pid = tmpMyFile.getPid();
            List<MyFile> tmpList = parentId2MyFileListMap.get(pid);
            if (tmpList == null) {
                tmpList = new ArrayList<>();
                parentId2MyFileListMap.put(pid, tmpList);
            }
            tmpList.add(tmpMyFile);
        }
        // 顶级节点
        myFile.setChildList(parentId2MyFileListMap.get(new Integer(0)));
        for (MyFile tmpMyFile : tmpMyFileList) {
            List<MyFile> childList = parentId2MyFileListMap.get(tmpMyFile.getId());
            if (childList != null) {
                tmpMyFile.setChildList(childList);
            }
        }

        return myFile;
    }

    /**
     * 获取ztree需要的数据格式
     *
     * @param fileList
     * @return
     */
    private List<MyFile> processMyFile(List<MyFile> fileList) {
        List<MyFile> rList = new ArrayList<>();

        int count = 1;
        for (MyFile myfile : fileList) {
            String entryName = myfile.getEntryName();
            String[] entryNames = entryName.split("/");
            for (int i = 0; i < entryNames.length; i++) {
                // 当前目录的名字
                String name = entryNames[i];
                // 父级目录
                String pPath = "";
                // 当前路径
                String path = "";
                for (int j = 0; j < i; j++) {
                    path += entryNames[j] + "/";
                    pPath += entryNames[j] + "/";
                }
                path += name + "/";
                // 如果当前路径不存在，则添加到目标lists中
                if (!exist(path, rList)) {
                    myfile.setId(count++);
                    // 根据父级目录获取父级目录的ID
                    myfile.setPid(getIdByPpath(pPath, rList));
                    myfile.setPath(path);
                    myfile.setParentPath(pPath);
                    if (name.length() > 20) {
                        name = "..." + name.substring(name.length() - 20, name.length());
                    }
                    myfile.setFileName(name);

                    rList.add(myfile);
                }
            }
        }
        return rList;
    }

    /**
     * 根据父级目录获取父级目录的ID
     *
     * @param pPath
     * @param lists
     * @return
     */
    private int getIdByPpath(String pPath, List<MyFile> lists) {
        for (MyFile myfile : lists) {
            String path = myfile.getPath();
            int id = myfile.getId();
            if (path.equals(pPath)) {
                return id;
            }
        }
        return 0;
    }

    /**
     * 当前路径是否已经存在
     *
     * @param path
     * @param lists
     * @return
     */
    private boolean exist(String path, List<MyFile> lists) {
        boolean flag = false;
        for (MyFile myfile : lists) {
            String tmpPath = myfile.getPath();
            if (path.equals(tmpPath)) {
                flag = true;
            }
        }
        return flag;
    }

	public static void main(String[] args) throws Exception {
		String path = "C:/Users/luqiang/Downloads/ReadZIPorRAR.zip";
		// 获取zip文件的目录结构
		// List<MyFile> list1 = new ReadZipStructService().readZipFile(path);
		// for (MyFile myfile : list1) {
		// System.out.println(myfile.toString());
		// }

		MyFile myFile = new ReadZipStructServiceImpl().getMyFile(path);
		String html = FileUtil.traverseZipFile(myFile, 0);
		System.out.println(html);
	}

}